package com.ruoyi.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.domain.*;
import com.ruoyi.web.domain.query.BhPlansPageQuery;
import com.ruoyi.web.domain.query.CreatePlanQuery;
import com.ruoyi.web.domain.query.ExecutePlanQuery;
import com.ruoyi.web.domain.query.PunchCardQuery;
import com.ruoyi.web.domain.vo.AppPlanDetailVO;
import com.ruoyi.web.domain.vo.BhPlansPageVO;
import com.ruoyi.web.domain.vo.ReportPageVO;
import com.ruoyi.web.mapper.BhPlansBillMapper;
import com.ruoyi.web.mapper.BhPlansMapper;
import com.ruoyi.web.mapper.BhReportMapper;
import com.ruoyi.web.mapper.BhRiskListMapper;
import com.ruoyi.web.service.BhPlansService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class BhPlansServiceImpl implements BhPlansService {
    @Autowired
    private BhPlansMapper baseMapper;
    @Autowired
    private BhReportMapper bhReportMapper;
    @Autowired
    private BhRiskListMapper bhRiskListMapper;
    @Autowired
    private BhPlansBillMapper bhPlansBillMapper;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysDictDataService dictDataService;

    /**
     * 获取计划分页数据
     *
     * @param bhPlansPageQuery 查询条件
     * @param pageQuery        分页参数
     * @param needTrans        是否需要全部数据
     * @return 计划分页数据
     */
    @Override
    public TableDataInfo<BhPlansPageVO> getPlanPage(BhPlansPageQuery bhPlansPageQuery, PageQuery pageQuery, boolean needTrans) {
        String name = bhPlansPageQuery.getExecutors();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(name)) {
            SysUser user = this.userService.selectUserByUserName(name);
            if (!Objects.isNull(user)) {
                bhPlansPageQuery.setExecutors(String.valueOf(user.getUserId()));
            }
        }
        LambdaQueryWrapper<BhPlans> lqw = buildQueryWrapper(bhPlansPageQuery);
        Page<BhPlansPageVO> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<BhPlansPageVO> plans = result.getRecords();
        if (!CollectionUtils.isEmpty(plans)) {
            fillNames(plans, needTrans);
        }
        return TableDataInfo.build(result);
    }

    // 组装分页查询条件
    private LambdaQueryWrapper<BhPlans> buildQueryWrapper(BhPlansPageQuery bhPlansPageQuery) {
        LambdaQueryWrapper<BhPlans> lqw = Wrappers.lambdaQuery();
        lqw.eq(BhPlans::getDelFlag, 0);
        lqw.eq(BhPlans::getTopId, 0);
        lqw.eq(StringUtils.isNotBlank(bhPlansPageQuery.getClassesed()), BhPlans::getClassesed, bhPlansPageQuery.getClassesed());
        lqw.eq(StringUtils.isNotBlank(bhPlansPageQuery.getStatus()), BhPlans::getStatus, bhPlansPageQuery.getStatus());
        lqw.apply(org.apache.commons.lang3.StringUtils.isNotBlank(bhPlansPageQuery.getExecutors()), "find_in_set({0},REPLACE(executors, '|', ','))", bhPlansPageQuery.getExecutors());
        lqw.orderByDesc(BhPlans::getCreateTime);
        return lqw;
    }

    // 填充字典数据
    private void fillNames(List<BhPlansPageVO> plans, boolean needTrans) {
        for (BhPlansPageVO plan : plans) {
            fillName(plan);
            if (needTrans) {
                String vehicles = dictDataService.selectDictLabel("car_mangers", plan.getVehicles());
                if (org.apache.commons.lang3.StringUtils.isNotBlank(vehicles)) {
                    plan.setVehicles(vehicles);
                }
                String classes = dictDataService.selectDictLabel("classes", plan.getClassesed());
                if (org.apache.commons.lang3.StringUtils.isNotBlank(classes)) {
                    plan.setClassesed(classes);
                }
                String status = dictDataService.selectDictLabel("check_plan_status", plan.getStatus());
                if (org.apache.commons.lang3.StringUtils.isNotBlank(status)) {
                    plan.setStatus(status);
                }
            }
        }
    }

    // 填充执行人姓名
    private void fillName(BhPlansPageVO plan) {
        List<String> names = new ArrayList<>();
        List<String> userIds = StringUtils.str2List(plan.getExecutors(), "[|]", true, true);
        if (!CollectionUtils.isEmpty(userIds)) {
            userIds.forEach(x -> {
                Long userId;
                try {
                    userId = Long.valueOf(x);
                    SysUser sysUser = userService.selectUserById(userId);
                    if (!Objects.isNull(sysUser)) {
                        names.add(sysUser.getNickName());
                    } else {
                        names.add(x);
                    }
                } catch (NumberFormatException e) {
                    names.add(x);
                }

            });
        }
        plan.setExecutorNames(names.stream().reduce((s1, s2) -> s1 + "|" + s2).orElse(""));
    }

    /**
     * 新建计划
     *
     * @param createPlanQuery 新建参数
     * @return 返回
     */
    @Transactional
    @Override
    public R<Void> createPlan(CreatePlanQuery createPlanQuery) {
        BhPlans addParam = new BhPlans();
        BeanUtils.copyProperties(createPlanQuery, addParam);
        addParam.setDelFlag(0);                 // 删除标志 0-未删除
        addParam.setStatus("3");                // 未执行
        addParam.setCreateTime(new Date());
        addParam.setTopId(0);
        // 创建人
        Long userId = LoginHelper.getUserId();
        addParam.setCreatedBy(String.valueOf(userId));
        // 新增计划主数据
        if (baseMapper.insert(addParam) <= 0) {
            return R.fail();
        }
        return insertSecondPlans(createPlanQuery, addParam.getId(), userId);
    }

    // 新增计划从数据
    @NotNull
    private R<Void> insertSecondPlans(CreatePlanQuery createPlanQuery, Integer topId, Long userId) {
        String reportId = createPlanQuery.getReportId();
        List<String> reportIds = StringUtils.str2List(reportId, "[|]", true, true);
        if (!CollectionUtils.isEmpty(reportIds)) {
            for (String id : reportIds) {
                BhPlans addPlan = new BhPlans();
                BeanUtils.copyProperties(createPlanQuery, addPlan);
                addPlan.setId(null);
                addPlan.setDelFlag(0);              // 未删除
                addPlan.setStatus("0");             // 未打卡
                addPlan.setCreateTime(new Date());
                addPlan.setReportId(id);
                addPlan.setTopId(topId);
                addPlan.setCreatedBy(String.valueOf(userId));
                addPlan.setIsModel("0");            // 非典型
                if (baseMapper.insert(addPlan) <= 0) {
                    return R.fail();
                }
            }
        }
        return R.ok();
    }

    /**
     * 获取计划详情
     *
     * @param id 计划id
     * @return 计划详情
     */
    @Override
    public R<BhPlansPageVO> getPlanDetail(Integer id) {
        BhPlansPageVO bhPlansPage = new BhPlansPageVO();
        BhPlans bhPlans = baseMapper.selectById(id);
        if (Objects.isNull(bhPlans)) {
            return R.fail("未找到对应数据");
        }
        BeanUtils.copyProperties(bhPlans, bhPlansPage);
        fillName(bhPlansPage);
        List<ReportPageVO> reports = new ArrayList<>();
        String reportId = bhPlans.getReportId();
        List<String> reportIds = StringUtils.str2List(reportId, "[|]", true, true);
        if (!CollectionUtils.isEmpty(reportIds)) {
            reportIds.forEach(x -> {
                ReportPageVO report = new ReportPageVO();
                BhReport bhReport = bhReportMapper.selectById(Integer.valueOf(x));
                if (!Objects.isNull(bhReport)) {
                    BeanUtils.copyProperties(bhReport, report);
                    List<String> ids = StringUtils.str2List(report.getProjectName(), "[|]", true, true);
                    List<BhRiskList> bhRiskLists = bhRiskListMapper.selectList(new LambdaQueryWrapper<BhRiskList>().in(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(ids), BhRiskList::getId, ids));
                    report.setProjectName(bhRiskLists.stream().map(entry -> entry.getName()).collect(Collectors.joining("|")));
                    reports.add(report);
                }
            });
        }
        bhPlansPage.setReportList(reports);
        return R.ok(bhPlansPage);
    }

    /**
     * 删除计划-逻辑删除
     *
     * @param id 计划id
     * @return 返回
     */
    @Transactional
    @Override
    public R<Void> delPlan(Integer id) {
        BhPlans bhPlans = baseMapper.selectById(id);
        if (Objects.isNull(bhPlans)) {
            return R.fail("未找到对应数据");
        }
        List<BhPlans> bhPlanList = baseMapper.selectList(new LambdaQueryWrapper<BhPlans>().eq(BhPlans::getTopId, bhPlans.getId()));
        if (!CollectionUtils.isEmpty(bhPlanList)) {
            for (BhPlans plans : bhPlanList) {
                if (baseMapper.deleteBhPlans(plans.getId()) <= 0) {
                    return R.fail("删除失败");
                }
            }
        }
        if (baseMapper.deleteBhPlans(id) > 0) {
            return R.ok();
        } else {
            return R.fail("删除失败");
        }
    }

    /**
     * 编辑计划
     *
     * @param modPlanQuery 修改参数
     * @return 返回
     */
    @Transactional
    @Override
    public R<Void> modPlan(CreatePlanQuery modPlanQuery) {
        BhPlans bhPlans = baseMapper.selectById(modPlanQuery.getId());
        if (Objects.isNull(bhPlans)) {
            return R.fail("未找到对应计划！");
        }
        // 只有未执行的计划才能编辑
        if (!"3".equals(bhPlans.getStatus())) {
            return R.fail("该计划不能编辑！");
        }
        Long userId = LoginHelper.getUserId();
        BhPlans modParam = new BhPlans();
        BeanUtils.copyProperties(modPlanQuery, modParam);
        modParam.setUpdatedBy(String.valueOf(userId));
        modParam.setUpdatedTime(new Date());
        if (baseMapper.updateById(modParam) <= 0) {
            return R.fail("编辑失败");
        }
        baseMapper.delete(new LambdaQueryWrapper<BhPlans>().eq(BhPlans::getTopId, modPlanQuery.getId()));
        return insertSecondPlans(modPlanQuery, modPlanQuery.getId(), userId);
    }

    /**
     * 计划 - 打卡 - app
     *
     * @param punchCardQuery 打卡参数
     * @return 返回
     */
    @Override
    public R<Void> punchCard(PunchCardQuery punchCardQuery) {
        BhPlans modParam = new BhPlans();
        BeanUtils.copyProperties(punchCardQuery, modParam);
        modParam.setStatus("1");            // 已打卡
        if (baseMapper.updateById(modParam) > 0) {
            return R.ok();
        } else {
            return R.fail("打卡失败");
        }
    }

    /**
     * 获取计划列表 - app
     *
     * @param id 计划id
     * @return 计划列表
     */
    @Override
    public R<List<AppPlanDetailVO>> getAppPlanList(Integer id) {
        List<AppPlanDetailVO> result = new ArrayList<>();
        LambdaQueryWrapper<BhPlans> lqw = new LambdaQueryWrapper<>();
        lqw.eq(BhPlans::getTopId, id);
        lqw.eq(BhPlans::getDelFlag, 0);
        List<BhPlans> bhPlans = baseMapper.selectList(lqw);
        if (!CollectionUtils.isEmpty(bhPlans)) {
            for (BhPlans bhPlan : bhPlans) {
                BhReport bhReport = bhReportMapper.selectById(bhPlan.getReportId());
                if (!Objects.isNull(bhReport)) {
                    AppPlanDetailVO appPlanDetail = new AppPlanDetailVO();
                    BeanUtils.copyProperties(bhReport, appPlanDetail);
                    BeanUtils.copyProperties(bhPlan, appPlanDetail);
                    List<String> ids = StringUtils.str2List(bhReport.getProjectName(), "[|]", true, true);
                    List<BhRiskList> bhRiskLists = bhRiskListMapper.selectList(new LambdaQueryWrapper<BhRiskList>().in(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(ids), BhRiskList::getId, ids).orderByAsc(BhRiskList::getId));
                    appPlanDetail.setProjectName(bhRiskLists.stream().map(entry -> entry.getName()).collect(Collectors.joining("|")));
                    fillData(appPlanDetail, bhRiskLists);
                    List<PlanBill> checkList = new ArrayList<>();
                    List<BhPlansBill> bhPlansBills = bhPlansBillMapper.selectList(new LambdaQueryWrapper<BhPlansBill>().eq(BhPlansBill::getDelFlag, 0).eq(BhPlansBill::getPlanId, bhPlan.getId()));
                    if (!CollectionUtils.isEmpty(bhPlansBills)) {
                        for (BhPlansBill bhPlansBill : bhPlansBills) {
                            PlanBill planBill = new PlanBill();
                            BeanUtils.copyProperties(bhPlansBill, planBill);
                            checkList.add(planBill);
                        }
                    } else {
                        List<String> list = StringUtils.str2List(bhReport.getRiskFactor(), "[|]", true, true);
                        if (!CollectionUtils.isEmpty(list)) {
                            for (String riskFactor : list) {
                                PlanBill planBill = new PlanBill();
                                planBill.setRiskFactor(riskFactor);
                                checkList.add(planBill);
                            }
                        }
                    }
                    appPlanDetail.setCheckList(checkList);
                    appPlanDetail.setId(bhPlan.getId());
                    result.add(appPlanDetail);
                }
            }
        }
        return R.ok(result);
    }

    // 填充参数
    private void fillData(AppPlanDetailVO appPlanDetail, List<BhRiskList> bhRiskLists) {
        Set<String> pointSet = new HashSet<>();
        Set<String> mainSet = new HashSet<>();
        for (BhRiskList bhRiskList : bhRiskLists) {
            LambdaQueryWrapper<BhRiskList> lqw = new LambdaQueryWrapper<>();
            lqw.eq(BhRiskList::getDelFlag, 0);
            lqw.eq(BhRiskList::getId, bhRiskList.getParentId());
            BhRiskList point = bhRiskListMapper.selectOne(lqw);
            if (!Objects.isNull(point)) {
                pointSet.add(point.getName());
                LambdaQueryWrapper<BhRiskList> mainLqw = new LambdaQueryWrapper<>();
                mainLqw.eq(BhRiskList::getDelFlag, 0);
                mainLqw.eq(BhRiskList::getId, point.getParentId());
                BhRiskList main = bhRiskListMapper.selectOne(mainLqw);
                if (!Objects.isNull(main)) {
                    mainSet.add(main.getName());
                }
            }
        }
        appPlanDetail.setPoint(pointSet.stream().reduce((s1, s2) -> s1 + "|" + s2).orElse(""));
        appPlanDetail.setMain(mainSet.stream().reduce((s1, s2) -> s1 + "|" + s2).orElse(""));
    }

    /**
     * 执行计划 - app
     *
     * @param executePlanQuery 执行参数
     * @return 返回
     */
    @Transactional
    @Override
    public R<Void> executePlan(ExecutePlanQuery executePlanQuery) {
        boolean canModFlag = true;
        List<BhPlansBill> bhPlansBills = bhPlansBillMapper.selectList(new LambdaQueryWrapper<BhPlansBill>().eq(BhPlansBill::getDelFlag, 0).eq(BhPlansBill::getPlanId, executePlanQuery.getId()));
        if (!CollectionUtils.isEmpty(bhPlansBills)) {
            for (BhPlansBill bhPlansBill : bhPlansBills) {
                if ("1".equals(bhPlansBill.getIsRectify())) {
                    canModFlag = false;
                    break;
                }
            }
        }
        if (canModFlag) {
            BhPlans modParam = new BhPlans();
            BeanUtils.copyProperties(executePlanQuery, modParam);
            // 从状态变为已检查
            modParam.setStatus("2");                // 已检查
            // 检查主状态
            BhPlans getMainParam = new BhPlans();
            getMainParam.setId(executePlanQuery.getId());
            BhPlans mainPlan = baseMapper.getMainPlan(getMainParam);
            if (Objects.isNull(mainPlan)) {
                return R.fail("未找到对应的主计划！");
            }
            BhPlans getOtherParam = new BhPlans();
            getOtherParam.setId(executePlanQuery.getId());
            getOtherParam.setTopId(mainPlan.getId());
            List<BhPlans> otherPlans = baseMapper.getOtherPlan(getOtherParam);
            boolean firstFlag = true;               // 是否首次标识
            boolean overFlag = true;                // 是否结束标志
            if (!CollectionUtils.isEmpty(otherPlans)) {
                for (BhPlans otherPlan : otherPlans) {
                    if (!"2".equals(otherPlan.getStatus())) {
                        overFlag = false;
                        break;
                    }
                }
                for (BhPlans otherPlan : otherPlans) {
                    if ("2".equals(otherPlan.getStatus())) {
                        firstFlag = false;
                        break;
                    }
                }
            }
            BhPlans modMainParam = new BhPlans();
            if (overFlag && !"1".equals(mainPlan.getStatus())) {
                modMainParam.setStatus("1");            // 已执行
            } else if (firstFlag && "3".equals(mainPlan.getStatus())) {
                modMainParam.setStatus("2");            // 执行中
            }
            modMainParam.setId(mainPlan.getId());
            baseMapper.updateById(modMainParam);
            Integer hiddenDangerNum = 0;                // 隐患数量
            List<PlanBill> planBills = executePlanQuery.getPlanBills();
            if (!CollectionUtils.isEmpty(planBills)) {
                modParam.setCheckNum(planBills.size());
                BhPlansBill delParam = new BhPlansBill();
                delParam.setDelFlag(1);                 // 删除
                bhPlansBillMapper.update(delParam, new LambdaQueryWrapper<BhPlansBill>().eq(BhPlansBill::getPlanId, executePlanQuery.getId()));
                for (PlanBill planBill : planBills) {
                    String inspectResult = planBill.getInspectResult();
                    if ("2".equals(inspectResult)) {
                        hiddenDangerNum++;
                    }
                    BhPlansBill addParam = new BhPlansBill();
                    BeanUtils.copyProperties(planBill, addParam);
                    addParam.setCreateTime(new Date());
                    addParam.setDelFlag(0);
                    addParam.setIsRectify("0");
                    addParam.setPlanId(executePlanQuery.getId());
                    addParam.setReportId(executePlanQuery.getReportId());
                    bhPlansBillMapper.insert(addParam);
                }
            }
            modParam.setHiddenDangerNum(hiddenDangerNum);
            modParam.setRiskStatus("1");
            if (baseMapper.updateById(modParam) <= 0) {
                return R.fail("执行计划失败");
            }
            return R.ok();
        } else {
            return R.fail("已有隐患在整改，不可提交！");
        }
    }

    /**
     * 获取检查计划个数 - app
     *
     * @return 计划个数
     */
    @Override
    public R<Integer> getPlanNum() {
        int num = 0;
        Long userId = LoginHelper.getUserId();
        List<BhPlans> bhPlans = baseMapper.selectList(new LambdaQueryWrapper<BhPlans>().eq(BhPlans::getDelFlag, 0).eq(BhPlans::getExecutors, userId));
        if (!CollectionUtils.isEmpty(bhPlans)) {
            num = bhPlans.size();
        }
        return R.ok(num);
    }
}
